#!/usr/bin/python


import marin


class LocalOrdinanceCalculator(object):
    """Encapsulates the data and algorithms used to calculate compliance
    with the Local Ordinance.
    Initialize it with data like this:
        lo_obj = LocalOrdinanceCalculator(
            cz=3,  # Climate Zone
            proj_name='Doe Residence',  # Project Name
            area=2345,  # Conditioned Floor Area (cfa)
            std=234.56,  # Standard building energy use in kBTU/sf-yr
            prop=123.45,  # Standard building energy use in kBTU/sf-yr
            pv_production=0.0,  # This argument is optional
            adjustment_factor_proposed=0.85,  # Optional, default 0.85
        )
    Get the adjustment factor with:
        print "The adjustment factor is:", lo_obj.adjustment_factor
    Test for compliance with:
        if lo_obj.complies: print "You comply!"
    """
    def __init__(self, **kwargs):
        """Initialize the object with as many keyword arguments as we can
        and just toss the ones we don't know about.
        """
        self.cz = kwargs['cz']
        self.proj_name = kwargs.get('proj_name', '')
        self.proj_addr = kwargs.get('proj_addr', '')
        self.proj_city = kwargs.get('proj_city', '')
        self.proj_state = kwargs.get('proj_state', '')
        self.proj_zipcode = kwargs.get('proj_zipcode', '')
        self.proj_zip4 = kwargs.get('proj_zip4', '')
        self.doc_author = kwargs.get('doc_author', '')
        self.doc_business = kwargs.get('doc_business', '')
        self.doc_addr = kwargs.get('doc_addr', '')
        self.doc_city = kwargs.get('doc_city', '')
        self.doc_state = kwargs.get('doc_state', '')
        self.doc_zipcode = kwargs.get('doc_zipcode', '')
        self.doc_phone = kwargs.get('doc_phone', '')
        self.bldg_type = kwargs.get('bldg_type', '')
        self.proj_name = kwargs.get('proj_name', '')
        self.area = kwargs.get('area', 0.0)
        self.std = kwargs.get('std', 0.0)
        self.prop = kwargs.get('prop', 0.0)
        self.pv_production = kwargs.get('pv_production', 0.0)
        self.adjustment_factor_proposed = kwargs.get('pv', 0.85)
        self.local_ordinance_module = kwargs.get('local_ordinance_module', None)

    def _get_adjustment_factor(self):
        """Returns the adjustment factor for the given Local Ordinance module.
        local_ordinance_module should be an imported module.  If the
        local_ordinance_module argument is missing, then the 'marin' module
        will be imported and used.

        The local ordinance has an adjustment factor to adjust standard
        t24 value in such a manner as to make compliance more difficult.
        This method uses the self.area to make the appropriate house area
        category selection.
        Lastly, using the matrix in the local_ordinance_module to pass the
        adjustment factor to calculate the adjusted Standard allotment.
        """
        if self.local_ordinance_module is None:
            self.local_ordinance_module = __import__(
                'title24_local_ordinance.marin'
            )
        n = 0
        if self.area > 11500:
            n=8
        elif self.area in range(10500,11500):
            n=7
        elif self.area in range(9500,10500):
            n=6
        elif self.area in range(8500,9500):
            n=5
        elif self.area in range(7500,8500):
            n=4
        elif self.area in range(6500,7500):
            n=3
        elif self.area in range(5500,6500):
            n=2
        elif self.area in range(4500,5500):
            n=1
        elif self.area in range(1500,4500):
            n=0
        else:
            # Return 1 because no adjustment is necessary
            return 1.0
        return self.local_ordinance_module.cz_Adjust[self.cz - 2][n]
    adjustment_factor = property(_get_adjustment_factor)

    def _get_revised_std(self):
        """Returns the standard building energy use, adjusted for the
        local ordinance.
        """
        return self.adjustment_factor * self.std
    revised_std = property(_get_revised_std)

    def _get_adjusted_proposed(self):
        """Returns the proposed energy use adjusted for PV energy, if any."""
        return self.prop - self.solar_pv_credit
    adjusted_prop = property(_get_adjusted_proposed)

    def _get_max_allowed_proposed(self):
        """Returns the maximum allowed proposed energy use."""
        return self.std * self.adjustment_factor_proposed
    max_allowed_proposed = property(_get_max_allowed_proposed)

    def _get_solar_pv_credit(self):
        """Returns the solar pv credit."""
        return self.pv_production / (0.293 * self.area)
    solar_pv_credit = property(_get_solar_pv_credit)

    def _project_complies(self):
        """Returns True if the project complies, False otherwise."""
        return self.prop <= self.revised_std
    complies = property(_project_complies)


def parse_dat_file(file_object):
    """Parses the file object and returns an EnergyProDatFile object that
    contains the parsed data.
    """
    aString = file_object.read(750)
    R = [field.strip() for field in aString.split('|')]
    return LocalOrdinanceCalculator(
        cz=int(R[4]),
        proj_name=R[5],
        proj_addr=R[6],
        proj_city=R[7],
        proj_state=R[8],
        proj_zipcode=R[9],
        proj_zip4=R[10],
        doc_author=R[11],
        doc_business=R[12],
        doc_addr=R[13],
        doc_city=R[14],
        doc_state=R[15],
        doc_zipcode=R[16],
        doc_phone=R[17],
        general_bldg_type=R[42],
        area=int(R[43]),
        std=float(R[62]),
        prop=float(R[75]),
        local_ordinance_module=marin,
    )


def dat_read():
    """Prompts the user for the path to the EnergyPro dat file and returns an
    EnergyProDatFile object that contains the parsed data.
    """

    from Tkinter import Tk
    import tkFileDialog

    master = Tk()
    master.withdraw() #hiding tkinter window

    file_path = tkFileDialog.askopenfilename(
        title="Open file",
        filetypes=[("dat file",".dat"),("All files",".*")]
    )
    if file_path != "":
        # Filepath will be something like:
        # 'C:\\EP4\\Res Sample.dat'
        myfile = open(file_path)
    else:
        print "you didn't open anything!"

    master.quit()
    calculator = parse_dat_file(myfile)
    myfile.close()

    return calculator
